#ifndef __XDO_SWF_EXPLOITS__
#define __XDO_SWF_EXPLOITS__

#include "../arch/swf/swf.hpp"
/*
	786DD1892B553EFE5A004AC39775C851		661C0000		0007D800
	23FDB0C309E188A5E3C767F8FC557D83		51BD0000		0008B000
*/

namespace xm
{
	class XdoSwfExploit : public IKDetector, UnkBase
	{
	public:
		UNKNOWN_IMP1( IKDetector );
		DEFAULT_INIT_CLASS();
	public:
		STDMETHOD(Detect)( IKDetectSession * sess, DetectResult * pdr )
		{
			iptr<IKFileStream> file = sess->TargetStream();
			if( !file ) return E_FAIL;
			RFAILED( file->SetPos(0) );
			swf::BxStream wrapper(file);
			swf::StreamIn ins(&wrapper);
			swf::FileHeader hdr;
			if( !hdr.read( ins ) ) return E_FAIL;
			if( hdr.sig0 != 'F' ) return E_FAIL; 
			return Detect(file,pdr);
		}
		STDMETHOD(Treat)( IKDetectSession * sess, DetectResult * pdr )
		{
			return sess->RawStream()->Remove();
		}
		STDMETHOD(Reset)()
		{
			return S_OK;
		}

	protected:

		HRESULT Detect( IKBStream * file, DetectResult * pdr )
		{
			swf::BxStream wrapper(file);
			swf::StreamIn ins(&wrapper);
			swf::FileHeader2 hdr2;
			if( !hdr2.read( ins ) )
				return E_FAIL;

			size_t susp_int = 0;

			while( 1 )
			{
				swf::Tag tag;
				if( !tag.read(ins) )
					break;
				//printf( "tag=%04X, length=%08X\n", tag.tag, tag.length );
				if( tag.tag == 69 )
				{
					swf::tag::FileAttributes fas;
					fas.read( ins );
				}
				else if( tag.tag == 82 )	// DoABC
				{
					uint64_t pos = ins.tell();
					swf::tag::DoABC doABC;
					neednz( doABC.read(ins) );
					size_t skipped = (size_t)(ins.tell() - pos);
					swf::abc::ABCData abcData;
					abcData.read( ins, tag.length - skipped );
					size_t ic = abcData.file.constant_pool.integers.items.size();
					for( size_t i = 0; i < ic; ++ i )
					{
						uint32_t iv = abcData.file.constant_pool.integers.items[i].i;
						if( iv > 0x51BD0000 && iv < 0x51BD0000 + 0x8B000 )
						{
							susp_int ++;
							if( susp_int > 8 ) 
							{
								pdr->Level = DLEV_MALW_HEUR; 
								return S_OK;
							}
						}
					}
				}
				else
				{
					ins.skip( tag.length );
				}
			}

			return E_FAIL;
		}
	};
};


#endif